﻿using System;
using System.ComponentModel;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Web;
using System.Security.Permissions;
using System.Collections.Generic;
using System.Data;

using BingZi.HY.Core;
using NewLife.Reflection;

namespace BingZi.WebControls
{
    /*－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
  * 自定义下拉框控件
  * 功能说明：1、通过设置IsAddEmpty（true）设置下拉框是否添加空选择项。
  *          2、通过设置IsAddAll来选择添加的空选择项是[Select]设为true,空选择项为[All]设为false
  *          3、通过给EnumType赋值来绑定枚举值
  －－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－*/
    [ToolboxData("<{0}:CustDropDownList runat=\"server\"> </{0}:CustDropDownList>")]
    public class CustDropDownList : DropDownList
    {
        #region 重写基类方法及属性


        /// <summary>
        /// 添加空选择项
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            //if (this.blAddEmpty)
            //{
            //    if (this.blAddAll)
            //    {
            //        //this.Items.Remove(new ListItem("[全部]", ""));
            //        this.Items.Remove(new ListItem("["+this.strAllText.Trim()+"]", ""));
            //        //this.Items.Insert(0, new ListItem("[全部]", ""));
            //        this.Items.Insert(0, new ListItem("[" + this.strAllText.Trim() + "]", ""));
            //    }
            //    else
            //    {
            //        //this.Items.Remove(new ListItem("[请选择]", ""));
            //        this.Items.Remove(new ListItem("[" + this.strEditText.Trim() + "]", ""));
            //        //this.Items.Insert(0, new ListItem("[请选择]", ""));
            //        this.Items.Insert(0, new ListItem("[" + this.strEditText.Trim() + "]", ""));
            //    }
            //}

            //【注】OnInit是控制在VS设计页面时的展现效果
            //AddDefaultItem();
            base.OnInit(e);
        }

        /// <summary>
        /// 添加空选择项
        /// </summary>
        public override void DataBind()
        {

            base.DataBind();
            //【注】之所以在DataBind()时，是因为下拉框在绑定时，很可能会将原有的信息给冲掉
            //因此必须在这里也加上，对【请选择】等项的新增

            AddDefaultItem();
        }
        /// <summary>
        ///update by junhuang 2009-1-15
        //修改下拉框，在VS编辑页面中，编辑属性其自动增加多个[请选择]的问题
        /// </summary>
        private void AddDefaultItem()
        {
            if (this.blAddEmpty)
            {
                if (this.blAddAll)
                {
                    if (this.Items.Count > 0 && this.Items[0].Text.StartsWith("["))
                    {
                        this.Items[0].Text = "[" + this.strAllText.Trim() + "]";
                        this.Items[0].Value = "";
                    }
                    else
                    {
                        this.Items.Insert(0, new ListItem("[" + this.strAllText.Trim() + "]", ""));
                    }
                }
                else
                {

                    if (this.Items.Count > 0 && this.Items[0].Text.StartsWith("["))
                    {
                        this.Items[0].Text = "[" + this.strEditText.Trim() + "]";
                        this.Items[0].Value = "";
                    }
                    else
                    {
                        this.Items.Insert(0, new ListItem("[" + this.strEditText.Trim() + "]", ""));
                    }
                }
            }
        }

        /// <summary>
        /// 输出控件
        /// </summary>
        /// <param name="writer"></param>
        protected override void Render(HtmlTextWriter writer)
        {
            if (this.Enabled)
            {

                string a = this.SelectedIndex.ToString();
                //this.SelectedIndex = this.SelectedIndex;
                base.Render(writer);

            }
            //Modify by junhuang 2009-1-13
            //如果下拉框Enable == false 则以Label形式输出
            else
            {
                string strText = this.SelectedItem == null ? "" : this.SelectedItem.Text;
                Label lblText = new Label();
                lblText.Text = strText;
                lblText.RenderControl(writer);
            }
        }

        /// <summary>
        /// 重写list控件使之能添加子控件
        /// </summary>
        /// <returns></returns>
        protected override ControlCollection CreateControlCollection()
        {
            return new ControlCollection(this);
        }



        #endregion



        #region --- 扩展属性
        private bool blAddEmpty = true;
        /// <summary>
        /// 是否添加空选择项
        /// </summary>
        [Category("CustProperty"), Description("是否添加空选择项")]
        public bool IsAddEmpty
        {
            get
            {
                return this.blAddEmpty;
            }
            set
            {
                this.blAddEmpty = value;
            }
        }

        private bool blAddAll = false;
        /// <summary>
        /// 空选择项为[All]设为true,空选择项为[Select]设为false
        /// </summary>
        [Category("CustProperty"), Description("空选择项为[全部]设为true,空选择项为[请选择]设为false")]
        public bool IsAddAll
        {
            get
            {
                return this.blAddAll;
            }
            set
            {
                this.blAddAll = value;
            }
        }

        private string strAllText = "全部";
        /// <summary>
        /// 查询时，空选择的文本，例如：全部
        /// </summary>
        [Category("CustProperty"), Description("查询时，空选择的文本，例如：全部")]
        public string AllText
        {
            get { return strAllText; }
            set { this.strAllText = value; }
        }

        private string strEditText = "请选择";
        /// <summary>
        /// 查询时，空选择的文本，例如：全部
        /// </summary>
        [Category("CustProperty"), Description("编辑时，空选择的文本，例如：请选择")]
        public string EditText
        {
            get { return strEditText; }
            set { this.strEditText = value; }
        }

        /// <summary>
        /// 下拉框绑定的枚举类型
        /// </summary>
        [Category("CustProperty"), Description("下拉框绑定的枚举类型")]
        public Type EnumType
        {
            set
            {
                this.DataSource = NewLife.Reflection.EnumHelper.GetEnumTable(value).DefaultView;
                this.DataTextField = "Text";
                this.DataValueField = "Value";
                this.DataBind();
            }
        }
        ///// <summary>
        ///// 样式
        ///// </summary>
        //[Category("CustProperty"), Description("样式，默认为ddl")]
        //public override string CssClass
        //{
        //    get { return this.CssClass; }
        //    set {this.CssClass = string.IsNullOrEmpty(value) ? "ddl" : value; }
        //}
        #endregion
    }





    public interface IDropDownTree : IDisposable
    {
        //// <summary>
        /// 返回Dictionary里分别对应ID,文本,如果没有子节点返回null
        /// </summary>
        /// <param name="parentID">父节点ID</param>
        /// <param name="Dt">数据源的表</param>
        /// <returns></returns>
        Dictionary<string, string> GetChildCategory(string parentID, List<object> Dt);
        //// <summary>
        /// 代码里写return new Interface.Common.DropDownTree(this);
        /// </summary>
        DropDownTree DropDownTree
        {
            get;
        }
    }
    public sealed class DropDownTree
    {
        IDropDownTree _DropDownTree;
        public DropDownTree(IDropDownTree dropDownTree)
        {
            _DropDownTree = dropDownTree;
        }
        //// <summary>
        /// 用于树的前缀
        /// </summary>
        /// <param name="IsLast">是否是同级节点中的最后一个</param>
        /// <param name="HasChild">本节点是否拥有子节点</param>
        /// <param name="ParentString">父节点前缀符号</param>
        /// <returns>本节点的前缀</returns>
        private string GetPreFix(bool isLast, bool hasChild, string parentString)
        {
            string result = string.Empty;
            if (!string.IsNullOrEmpty(parentString))
            {
                parentString = parentString.Remove(parentString.Length - 1).Replace("├", "│").Replace("└", "　");
                result += parentString;
            }
            if (isLast)
            {
                result += "└";
            }
            else
            {
                result += "├";
            }
            if (hasChild)
            {
                result += "┬";
            }
            else
            {
                result += "─";
            }
            return result;
        }
        #region 绑定下拉菜单

        //// <summary>
        /// 绑定连动级的下拉菜单
        /// </summary>
        /// <param name="ddlGoodsType">传进一个被绑定的DropDownList</param>
        /// <param name="removeID">被排除绑定的节点ID</param>
        /// <param name="AutoDispose">是否自动释放</param>
        /// <param name="Dt">分类的表</param>
        public void BindToDropDownList(DropDownList ddlGoodsType, string removeID, string parentID, bool autoDispose, List<Object> lst)
        {
            if (ddlGoodsType != null)
            {
                ListItem listItem = null;
                string currentID = parentID;//根节点/父ID
                string currentSign = string.Empty;//当前节点符号;
                string parrentSign = string.Empty; //父节点符号;
                bool HasChild = true;//是否有子
                Queue<string> parentKeyList = new Queue<string>();//存 有子节点的 节点ID
                Queue<string> parentSignList = new Queue<string>();//对应节点ID的前缀符号
                int itemIndexOf = 0;//父节点所在的位置　
                while (HasChild)
                {
                    int lastOneCount = 1;//用于计算在同级别中是否最后一个
                    Dictionary<string, string> childList = _DropDownTree.GetChildCategory(currentID, lst);// 得到子节点列表
                    if (childList != null && childList.Count > 0)
                    {
                        if (!string.IsNullOrEmpty(removeID) && childList.ContainsKey(removeID))
                        {
                            childList.Remove(removeID);
                        }
                        foreach (KeyValuePair<string, string> entry in childList)
                        {
                            if (_DropDownTree.GetChildCategory(entry.Key, lst) != null)//存在子
                            {
                                currentSign = GetPreFix(lastOneCount == childList.Count, true, parrentSign);
                                listItem = new ListItem(currentSign + entry.Value, entry.Key);

                                parentKeyList.Enqueue(entry.Key);//当前的节点ID
                                parentSignList.Enqueue(currentSign);//当前的节点符号
                            }
                            else//不存在子
                            {
                                currentSign = GetPreFix(lastOneCount == childList.Count, false, parrentSign);
                                listItem = new ListItem(currentSign + entry.Value, entry.Key);
                            }
                            if (ddlGoodsType.Items.Count != 0)
                            {
                                itemIndexOf = string.IsNullOrEmpty(currentID) ? itemIndexOf + 1 : ddlGoodsType.Items.IndexOf(ddlGoodsType.Items.FindByValue(currentID)) + lastOneCount;
                            }
                            ddlGoodsType.Items.Insert(itemIndexOf, listItem);//添加子节点
                            lastOneCount++;
                        }
                        if (parentKeyList.Count > 0)//存在子节点时
                        {
                            currentID = parentKeyList.Dequeue();
                            parrentSign = parentSignList.Dequeue();
                        }
                        else
                        {
                            HasChild = false;
                        }
                    }
                    else
                    {
                        break;
                    }


                }
                if (autoDispose)
                {
                    _DropDownTree.Dispose();
                }

            }
        }
        //// <summary>
        /// 绑定连动级的下拉菜单
        /// </summary>
        /// <param name="ddlGoodsType">传进一个被绑定的DropDownList</param>
        public void BindToDropDownList(DropDownList ddlGoodsType, List<Object> lst)
        {
            BindToDropDownList(ddlGoodsType, string.Empty, "0", true, lst);
        }
        //// <summary>
        /// 绑定连动级的下拉菜单
        /// </summary>
        /// <param name="ddlGoodsType">传进一个被绑定的DropDownList</param>
        /// <param name="removeID">被排除的ID</param>
        public void BindToDropDownList(DropDownList ddlGoodsType, string removeID, List<Object> lst)
        {
            BindToDropDownList(ddlGoodsType, removeID, "0", true, lst);
        }
        //// <summary>
        /// 绑定连动级的下拉菜单
        /// </summary>
        /// <param name="ddlGoodsType">传进一个被绑定的DropDownList</param>
        /// <param name="removeID">被排除的ID,若没有,传null</param>
        /// <param name="parentID">起始父ID</param>
        public void BindToDropDownList(DropDownList ddlGoodsType, string removeID, string parentID, List<Object> lst)
        {
            BindToDropDownList(ddlGoodsType, removeID, parentID, true, lst);
        }
        #endregion
    }
}
